// -*- mode: rust; -*-
//
// This file is part of curve25519-dalek.
// Copyright (c) 2018-2019 Henry de Valence
// See LICENSE for licensing information.
//
// Authors:
// - Henry de Valence <hdevalence@hdevalence.ca>

//! This module contains constants used by the IFMA backend.

use crate::backend::vector::packed_simd::u64x4;

#[cfg(feature = "precomputed-tables")]
use crate::window::NafLookupTable8;

use super::edwards::{CachedPoint, ExtendedPoint};
use super::field::{F51x4Reduced, F51x4Unreduced};

/// The identity element as an `ExtendedPoint`.
pub(crate) static EXTENDEDPOINT_IDENTITY: ExtendedPoint = ExtendedPoint(F51x4Unreduced([
    u64x4::new_const(0, 1, 1, 0),
    u64x4::new_const(0, 0, 0, 0),
    u64x4::new_const(0, 0, 0, 0),
    u64x4::new_const(0, 0, 0, 0),
    u64x4::new_const(0, 0, 0, 0),
]));

/// The identity element as a `CachedPoint`.
pub(crate) static CACHEDPOINT_IDENTITY: CachedPoint = CachedPoint(F51x4Reduced([
    u64x4::new_const(121647, 121666, 243332, 2251799813685229),
    u64x4::new_const(2251799813685248, 0, 0, 2251799813685247),
    u64x4::new_const(2251799813685247, 0, 0, 2251799813685247),
    u64x4::new_const(2251799813685247, 0, 0, 2251799813685247),
    u64x4::new_const(2251799813685247, 0, 0, 2251799813685247),
]));

/// Odd multiples of the Ed25519 basepoint:
#[cfg(feature = "precomputed-tables")]
pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = NafLookupTable8([
    CachedPoint(F51x4Reduced([
        u64x4::new_const(1277522120965857, 73557767439946, 243332, 1943719795065404),
        u64x4::new_const(108375142003455, 341984820733594, 0, 2097709862669256),
        u64x4::new_const(150073485536043, 750646439938056, 0, 581130035634455),
        u64x4::new_const(2149983732744869, 1903255931888577, 0, 646644904824193),
        u64x4::new_const(291045673509296, 1060034214701851, 0, 325245010451737),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1970681836121889,
            1660307753655178,
            1077207637163462,
            1436413309977108,
        ),
        u64x4::new_const(
            158785710838757,
            919645875412951,
            174577133496574,
            2213787394009350,
        ),
        u64x4::new_const(
            1017606396438281,
            1240932851489554,
            918203302506967,
            1239827708070863,
        ),
        u64x4::new_const(
            1748989883612327,
            1745367742532782,
            1168385548387,
            1211387683826673,
        ),
        u64x4::new_const(
            799349980018733,
            1471088235739693,
            1505351346057417,
            2104975925096407,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            171437462972293,
            36016853025886,
            1184164975342640,
            1633525003912147,
        ),
        u64x4::new_const(
            2113383632509037,
            1946216474924125,
            1884174984466256,
            1373317790955847,
        ),
        u64x4::new_const(
            791293623466401,
            1796466048084189,
            444977763198796,
            629823271230872,
        ),
        u64x4::new_const(
            1093217720067380,
            2157024270666135,
            238122980108466,
            806820763806847,
        ),
        u64x4::new_const(
            793658959468458,
            368578641413741,
            11592529764159,
            2144017075993471,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1538027396670268,
            1588896993892061,
            675619548648376,
            788373514423313,
        ),
        u64x4::new_const(
            1987517656073805,
            1940987929951188,
            666993851697339,
            2040540928108427,
        ),
        u64x4::new_const(
            375514548584082,
            1726008037083790,
            1070069155000872,
            570111103756303,
        ),
        u64x4::new_const(
            772223645372213,
            2123395244967674,
            868238486911408,
            1846639042240362,
        ),
        u64x4::new_const(
            872865734460736,
            32277956842850,
            1701451131455402,
            773883376061880,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1845177363882902,
            275858237213625,
            1052127336883600,
            171072805852218,
        ),
        u64x4::new_const(
            139016783952609,
            462699304987089,
            430046471494974,
            410922720999257,
        ),
        u64x4::new_const(
            846403935976337,
            243817706931454,
            971825428236901,
            571800039596794,
        ),
        u64x4::new_const(
            807642685434918,
            1933536976438782,
            812324278898440,
            688391556487313,
        ),
        u64x4::new_const(
            76239450396192,
            629532732688863,
            1833302026979779,
            650067934544499,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1373931604989264,
            331159264656614,
            364391529321767,
            874765630865409,
        ),
        u64x4::new_const(
            2109908262150241,
            473400816504190,
            91544045127333,
            976307977609515,
        ),
        u64x4::new_const(
            330175435673491,
            2126511895885904,
            1022944071588421,
            2158480209801463,
        ),
        u64x4::new_const(
            1305666795527971,
            162063591028664,
            2193154870675382,
            1789166662611800,
        ),
        u64x4::new_const(
            817858592500508,
            1672743239440202,
            859976879916778,
            1167423340862516,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            274334925170164,
            565841102587251,
            603083835949120,
            607539210240861,
        ),
        u64x4::new_const(
            196754662972649,
            1339063476699167,
            1406077076979491,
            896902435668469,
        ),
        u64x4::new_const(
            397962210956733,
            174839587476217,
            1381082665748936,
            175195877334136,
        ),
        u64x4::new_const(
            717429432748391,
            1635309821746318,
            363374010274647,
            882908746261699,
        ),
        u64x4::new_const(
            600946602802781,
            1946596133370711,
            1532135183320341,
            690530671668253,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            2074443704000945,
            2163534804938345,
            425423840926528,
            1100826171404853,
        ),
        u64x4::new_const(
            111700142796101,
            1456893872751964,
            1186145518682968,
            2192182627706116,
        ),
        u64x4::new_const(
            1848722121856066,
            2123239575044749,
            1323870754599272,
            883211262889775,
        ),
        u64x4::new_const(
            938263017712916,
            689670293631396,
            183944529557576,
            501908638166580,
        ),
        u64x4::new_const(
            2170571907220631,
            36636756989655,
            1875035480138608,
            803703278398018,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1053429956874064,
            1636640618139765,
            1556890827801070,
            2142720579528828,
        ),
        u64x4::new_const(
            1814240918422814,
            692326274601777,
            1054896561802157,
            2025454041705534,
        ),
        u64x4::new_const(
            2109495823888757,
            1287497869997176,
            194170063200096,
            621116840113213,
        ),
        u64x4::new_const(
            2156505873679998,
            2197064359737385,
            1312887672223536,
            369862818895912,
        ),
        u64x4::new_const(
            977381163563657,
            1878897311974033,
            2144566861359744,
            1832960882773351,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1266492498289486,
            1301524759372145,
            324789537938521,
            442710471023019,
        ),
        u64x4::new_const(
            1232722320001345,
            1191193089162455,
            176474006074813,
            2158950213252857,
        ),
        u64x4::new_const(
            1901782191467749,
            494791441598902,
            1820415815322129,
            854954583485223,
        ),
        u64x4::new_const(
            1511383667649702,
            792536415032464,
            2027741263854728,
            1727944381044738,
        ),
        u64x4::new_const(
            606355788891204,
            1670687521471220,
            582824350365415,
            1509135066079912,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1079942762813598,
            2015830004785901,
            479916361323351,
            1907956590950158,
        ),
        u64x4::new_const(
            2053400302939156,
            1319799126867070,
            19493088767391,
            1908755581402373,
        ),
        u64x4::new_const(
            2235858054780980,
            885832711204321,
            810332865560178,
            103174191215441,
        ),
        u64x4::new_const(
            1843466881032833,
            355511728384038,
            693846715794114,
            186545012724117,
        ),
        u64x4::new_const(
            1661758432892509,
            1491022339899281,
            698941123765263,
            174945407208560,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1075933251927831,
            400263885306647,
            1308157532880528,
            347933379126665,
        ),
        u64x4::new_const(
            673811632329433,
            1584860147186478,
            271778891257244,
            498194055154207,
        ),
        u64x4::new_const(
            703783427747558,
            1051624728592032,
            1371463103351544,
            230351033002960,
        ),
        u64x4::new_const(
            860729466483372,
            421647596766583,
            1520613871336707,
            635298775280054,
        ),
        u64x4::new_const(
            1168352891728845,
            1691216293752089,
            1799491997061519,
            399728882318504,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            420156727446514,
            1483649215777128,
            165508610199900,
            1918121104840431,
        ),
        u64x4::new_const(
            2129902293682427,
            730952770435213,
            2184527544565390,
            1939880362232986,
        ),
        u64x4::new_const(
            1771978364905086,
            510975579746524,
            927564335219142,
            177574146260558,
        ),
        u64x4::new_const(
            2164104536437514,
            1532598873799015,
            406875369182421,
            1367005937406517,
        ),
        u64x4::new_const(
            35073200082587,
            1981124717036219,
            1854087014063833,
            122419694385217,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1963785875777739,
            411497142699119,
            1974557512687408,
            1268304422747183,
        ),
        u64x4::new_const(
            762752575978150,
            1443822019541748,
            1331556159904338,
            377726798263780,
        ),
        u64x4::new_const(
            825953972847841,
            353487068141356,
            1955697322427207,
            2048226560172078,
        ),
        u64x4::new_const(
            1482378558684434,
            657691905625918,
            923870001994493,
            1694132799397736,
        ),
        u64x4::new_const(
            1643904759603122,
            170495566698285,
            1218312703413378,
            784318735038131,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            939230507241903,
            2238763473105245,
            1827325199528162,
            1153939339775538,
        ),
        u64x4::new_const(
            38544505283339,
            258889431497015,
            351721979677947,
            1357907379592829,
        ),
        u64x4::new_const(
            1393974676373341,
            1131355528938676,
            473104915298872,
            978783482501776,
        ),
        u64x4::new_const(
            2131516168980501,
            2113911780991092,
            1477027502354261,
            542884524860340,
        ),
        u64x4::new_const(
            1029606261349423,
            64226378557628,
            1669131167474348,
            2212808057234874,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1423176501543193,
            163313632579593,
            2220495688893001,
            2220041045291870,
        ),
        u64x4::new_const(
            1111834224023697,
            1026815658023689,
            1404605100939775,
            1412149108248227,
        ),
        u64x4::new_const(
            1542537854906076,
            1270288391129127,
            991419278941933,
            1824939809581980,
        ),
        u64x4::new_const(
            1142003215657891,
            525980550896367,
            1508270666157963,
            917719462309053,
        ),
        u64x4::new_const(
            400851268057105,
            1620818232405188,
            1251478578139510,
            2162841805361886,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            2125383272208441,
            1368790097335984,
            11813369275978,
            639513785921674,
        ),
        u64x4::new_const(
            2200806265616284,
            1041996387620216,
            1275149397833084,
            1723371028064068,
        ),
        u64x4::new_const(
            603720163891275,
            2135593511176153,
            2049641644431548,
            1198460677818310,
        ),
        u64x4::new_const(
            1862491879401621,
            2008116580769441,
            626566325260235,
            1058308304975798,
        ),
        u64x4::new_const(
            628557314314858,
            1075323332046522,
            1631772244117095,
            1812174547405683,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1222773123817104,
            363276129291452,
            796237592807883,
            1914425291893078,
        ),
        u64x4::new_const(
            1721259057429088,
            734941709009373,
            1553365830564638,
            1492120931079419,
        ),
        u64x4::new_const(
            1009354843273686,
            293884504384873,
            1050281954944357,
            134132942667344,
        ),
        u64x4::new_const(
            23119363298711,
            1694754778833445,
            1725925193393496,
            1738396998222001,
        ),
        u64x4::new_const(
            1753692057254667,
            118428526447110,
            840961387840295,
            1227619055408558,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1004186117579547,
            508771992330056,
            1426571663072421,
            2238524171903259,
        ),
        u64x4::new_const(
            744764613007812,
            398885442368825,
            2047459490294949,
            2141797621077959,
        ),
        u64x4::new_const(
            4556204156489,
            1708213022802363,
            1071381560923933,
            393474529142567,
        ),
        u64x4::new_const(
            350116198213005,
            945907227204695,
            168267474358731,
            1801504420122711,
        ),
        u64x4::new_const(
            728788674520360,
            1262722049156121,
            455259596607008,
            1159442365834489,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            2226818917892677,
            185673745808179,
            2240952219732549,
            324137961621908,
        ),
        u64x4::new_const(
            1659527641857410,
            973964060249383,
            1349692151487730,
            1172743533370593,
        ),
        u64x4::new_const(
            310591478467746,
            2123977244137170,
            774562885265820,
            430035546191685,
        ),
        u64x4::new_const(
            2150863173197992,
            2101978317708856,
            193592648406011,
            1375328504508580,
        ),
        u64x4::new_const(
            1946235834250479,
            121741431658675,
            1004342690620100,
            2063466488599450,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            463079632200153,
            40415275714025,
            545935352782679,
            1458043501600908,
        ),
        u64x4::new_const(
            783771976559993,
            880839641726471,
            1782028201271831,
            41664413404590,
        ),
        u64x4::new_const(
            985129151724159,
            187728621410000,
            16620051933318,
            378011085567733,
        ),
        u64x4::new_const(
            1820372198168638,
            905710046480679,
            1912961774249737,
            1868135861067161,
        ),
        u64x4::new_const(
            474460473983187,
            1455684425673661,
            652771171116843,
            733511920760779,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1088886980746809,
            1660218575261626,
            527921875040240,
            915086639857889,
        ),
        u64x4::new_const(
            1814735788528175,
            1586698876186367,
            2040856637532862,
            405684812785624,
        ),
        u64x4::new_const(
            658578559700999,
            1751442070931114,
            1293623371490094,
            715026719042518,
        ),
        u64x4::new_const(
            382156225644820,
            897982285504960,
            577673183555858,
            1158728558309719,
        ),
        u64x4::new_const(
            1865791902475663,
            124491617513788,
            758484125168765,
            734065580770143,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            330985690350617,
            2214424721795630,
            973374650780848,
            1507267060932964,
        ),
        u64x4::new_const(
            1733823971011290,
            1730742552292995,
            669018866977489,
            604527664126146,
        ),
        u64x4::new_const(
            1082092498645474,
            1029182053935309,
            756799947765834,
            1764720030308351,
        ),
        u64x4::new_const(
            969912105693756,
            38116887248276,
            2148030115687613,
            995140534653865,
        ),
        u64x4::new_const(
            2154373397460354,
            298128883464656,
            479587543632539,
            1061127201140779,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            843064865526549,
            2019481782959016,
            1873125524281672,
            2013330239022371,
        ),
        u64x4::new_const(
            1192932403815186,
            1818108671859220,
            1247005102016258,
            1210577394628058,
        ),
        u64x4::new_const(
            132359273326717,
            795492788299178,
            1235924489372816,
            891705064411550,
        ),
        u64x4::new_const(
            1425833709104858,
            152114045731085,
            991347902581315,
            1387773338707683,
        ),
        u64x4::new_const(
            48024203807922,
            157005564892977,
            1474053161953744,
            727448023498345,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1076621484026788,
            1309917234320927,
            1786998180233659,
            1595497085944737,
        ),
        u64x4::new_const(
            1737334672694726,
            2038133716999447,
            1929061192400917,
            620544235219084,
        ),
        u64x4::new_const(
            1550527313469747,
            329096759623509,
            1585214659209474,
            693419841748324,
        ),
        u64x4::new_const(
            1450010875912315,
            2085047082180569,
            757421110771886,
            389367139787400,
        ),
        u64x4::new_const(
            781339490566117,
            132941783448971,
            258650459725225,
            2042274962585613,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            859638991542650,
            2249840007426442,
            1138753070862357,
            793751342318913,
        ),
        u64x4::new_const(
            2133476133447306,
            1027010646129239,
            436851910892865,
            866949948830344,
        ),
        u64x4::new_const(
            1936003572431223,
            531513680252193,
            1929877059408416,
            830585477662503,
        ),
        u64x4::new_const(
            1460760405777960,
            686673748420916,
            275475330051554,
            1581792376993692,
        ),
        u64x4::new_const(
            894482039456784,
            1801274480988632,
            16407898635278,
            1668497039215206,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            258585746227669,
            936490904651492,
            1826793887434108,
            1201219990633823,
        ),
        u64x4::new_const(
            979462791643635,
            461762372210187,
            218708929991480,
            1378150755760178,
        ),
        u64x4::new_const(
            642542170229970,
            787135445552820,
            371168855880557,
            182642566486693,
        ),
        u64x4::new_const(
            1152277399721904,
            1726910452705576,
            1452393215705343,
            2117799581546845,
        ),
        u64x4::new_const(
            1211265143925330,
            14373046151823,
            1745528818271507,
            1842106288572078,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            635154614562157,
            1956763034454109,
            509123035953043,
            445727657534780,
        ),
        u64x4::new_const(
            2072765509783252,
            1282639891593570,
            1075086397362049,
            722996110178195,
        ),
        u64x4::new_const(
            1385572918825603,
            1190035835509576,
            218317841176013,
            1047865370756924,
        ),
        u64x4::new_const(
            473991569426488,
            1910588123704592,
            1338270051770806,
            401676861680875,
        ),
        u64x4::new_const(
            992455353618436,
            126422733426929,
            1955248037756399,
            119233843022643,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1555272991526078,
            2214378187116349,
            366893798097444,
            1401502118355702,
        ),
        u64x4::new_const(
            1157229521930713,
            2144787187506262,
            1681597469697840,
            847499096518697,
        ),
        u64x4::new_const(
            1872802655800758,
            1027119609820793,
            1137278714788290,
            1664750301179485,
        ),
        u64x4::new_const(
            1091289858897030,
            910126419483563,
            1101920147235731,
            597083075893952,
        ),
        u64x4::new_const(
            1711011533670315,
            185206680336278,
            1620960612579784,
            1968598849170880,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            73077300235958,
            257216723095630,
            466947267713785,
            847105214181598,
        ),
        u64x4::new_const(
            1322905631406309,
            407458059314731,
            230045063190376,
            923800751267786,
        ),
        u64x4::new_const(
            1146027205000415,
            1541328763727623,
            768510249199119,
            1630223587589059,
        ),
        u64x4::new_const(
            1930368769879433,
            1376145403022159,
            1898149855343131,
            1709421930518180,
        ),
        u64x4::new_const(
            633944191571764,
            58314960742839,
            2050971151574988,
            757799756090059,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            361576929158539,
            1035682890165818,
            160945739362874,
            266975208626222,
        ),
        u64x4::new_const(
            1635371797076046,
            2106722851965197,
            451585919077206,
            6692426667180,
        ),
        u64x4::new_const(
            175820543533852,
            2057511393764025,
            1531846543720469,
            1648320903946519,
        ),
        u64x4::new_const(
            947461770620940,
            1107335044817620,
            1725565474111216,
            2182263619949220,
        ),
        u64x4::new_const(
            726444888601221,
            1379664085279206,
            1517215633290417,
            1763968936542507,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            686545355846512,
            1712283265573167,
            1743509592736302,
            1653906616429153,
        ),
        u64x4::new_const(
            985108805667149,
            2244347650874753,
            1304749057936860,
            321846134330589,
        ),
        u64x4::new_const(
            296321076156886,
            1717929256240029,
            450933772486425,
            2015536856431605,
        ),
        u64x4::new_const(
            1690393512821866,
            646913049470189,
            2198650647576397,
            1230646705710442,
        ),
        u64x4::new_const(
            601961913448442,
            878806578800541,
            620497587492381,
            330716414244629,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            631510982676132,
            1755753187697174,
            1596201246674299,
            2197888384902121,
        ),
        u64x4::new_const(
            626957678275745,
            1447583371478595,
            1375375216702128,
            1443613232818823,
        ),
        u64x4::new_const(
            1962997804660501,
            1051744123184519,
            1002558639300437,
            1237313314603385,
        ),
        u64x4::new_const(
            2118828335274995,
            226398203764759,
            889099617161107,
            1620967117678504,
        ),
        u64x4::new_const(
            227261019362935,
            2046897556746842,
            591524060355369,
            2178552047369691,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1375403119051662,
            222313965014452,
            539873444241395,
            213198095917915,
        ),
        u64x4::new_const(
            1436952871599114,
            1229749762725246,
            1174441562267670,
            265367077740349,
        ),
        u64x4::new_const(
            11107426165917,
            985954476039181,
            1147329112365579,
            1133931640328107,
        ),
        u64x4::new_const(
            585235055006843,
            699515259687482,
            299559608721134,
            2134819767146767,
        ),
        u64x4::new_const(
            1376401105588528,
            391412107507860,
            302743651807545,
            1362834426455518,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1802940904616205,
            1615132760193234,
            869321663313735,
            666494072545310,
        ),
        u64x4::new_const(
            1452849320020701,
            1472716813676364,
            472862999490802,
            359937983286145,
        ),
        u64x4::new_const(
            1221198323133843,
            491718521756528,
            1387135774113906,
            793779904904008,
        ),
        u64x4::new_const(
            1032129287829151,
            30730741946697,
            217603185195068,
            2118169309744162,
        ),
        u64x4::new_const(
            225899335574721,
            1767553399797342,
            881082465669982,
            1435383196392870,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1127093564374276,
            2245188499702906,
            1250041622887441,
            2179324911668149,
        ),
        u64x4::new_const(
            908019210866875,
            1879900391060964,
            1355047706206597,
            647218945377302,
        ),
        u64x4::new_const(
            1616265604422592,
            2134336781521657,
            1157711219915601,
            1227494173135033,
        ),
        u64x4::new_const(
            136450294813355,
            1984543542455033,
            1199486053011083,
            33687889941331,
        ),
        u64x4::new_const(
            1053447012707371,
            68239344331930,
            537448158443925,
            1829189783369646,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            996806463322563,
            2043104667851348,
            1110361398300309,
            1218740346887957,
        ),
        u64x4::new_const(
            399141907016839,
            1307691109658227,
            532535384961264,
            896201194398872,
        ),
        u64x4::new_const(
            111705272106160,
            1790972382466021,
            1159338112559144,
            303544352897203,
        ),
        u64x4::new_const(
            1036600573322969,
            1457119922663674,
            334117653665514,
            460023361701263,
        ),
        u64x4::new_const(
            1363773215189933,
            1915594049343802,
            1661249423378694,
            1744945551969247,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            3093919631215,
            574886478077610,
            1704446919728971,
            250093147254210,
        ),
        u64x4::new_const(
            1387413348737796,
            360142717826981,
            2116185073015983,
            474541388374100,
        ),
        u64x4::new_const(
            1632539630892580,
            1332404016215719,
            2145297637794728,
            1289783723173504,
        ),
        u64x4::new_const(
            1030244179060173,
            579782698595797,
            1062365251139982,
            677149839815546,
        ),
        u64x4::new_const(
            6671539419876,
            1426937459653775,
            406942403696343,
            675479224223817,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            271984148441782,
            1708099625818957,
            1499011822959235,
            516808451044836,
        ),
        u64x4::new_const(
            1124847751346323,
            2038336022958449,
            1721698491022600,
            705944403212572,
        ),
        u64x4::new_const(
            85459783780275,
            1715213099986669,
            1728445509034791,
            730657630359717,
        ),
        u64x4::new_const(
            1185034652652387,
            755472578204310,
            476118360897817,
            1800434542785310,
        ),
        u64x4::new_const(
            1815589628676941,
            491778500674079,
            1547664984392513,
            279891608681267,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            2036337168672113,
            1730787524684269,
            639134121311693,
            698060925015524,
        ),
        u64x4::new_const(
            315211075189491,
            1329055848835358,
            688621136402134,
            1271193060119448,
        ),
        u64x4::new_const(
            1697984374314012,
            459330773536457,
            305481314707918,
            61676911066002,
        ),
        u64x4::new_const(
            2166631826859191,
            2105217187401781,
            937587962768434,
            357397435365683,
        ),
        u64x4::new_const(
            1206757093145471,
            1287847622009294,
            1951336140421622,
            2233789834777410,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            82144190081093,
            1568417433687791,
            907555979158442,
            2037855062523867,
        ),
        u64x4::new_const(
            1225315484058853,
            315317868015613,
            1765025920288384,
            175223259828436,
        ),
        u64x4::new_const(
            1215010304871271,
            662713408454950,
            429517658575616,
            991062684008811,
        ),
        u64x4::new_const(
            993837615254894,
            1485561584889450,
            2001836754226476,
            1915943063896801,
        ),
        u64x4::new_const(
            818895101625673,
            1342479472068804,
            1380235330010671,
            23315169761453,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1500726307559118,
            956166860173424,
            512663951564436,
            1940180717699824,
        ),
        u64x4::new_const(
            1789521472720825,
            779456898652427,
            2035063615853504,
            863582140589407,
        ),
        u64x4::new_const(
            634508890793787,
            1748041666732214,
            259642099961634,
            1294936839797812,
        ),
        u64x4::new_const(
            2183334898697038,
            2197242820694806,
            2217225409073703,
            992633998226449,
        ),
        u64x4::new_const(
            2197077498155916,
            1562008797791883,
            1395088759904208,
            331715244679294,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            186854731652320,
            284389440026580,
            1252175415119400,
            1025377410100223,
        ),
        u64x4::new_const(
            1578732129417607,
            898645497852382,
            2237766074482974,
            1939197790303592,
        ),
        u64x4::new_const(
            1438830390640145,
            1682452015845597,
            1108441197232223,
            1984134492898664,
        ),
        u64x4::new_const(
            282668727301669,
            1609018289552856,
            390363439795705,
            1138459124667912,
        ),
        u64x4::new_const(
            18889015928490,
            532489638086725,
            324621535996080,
            2210046082697453,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            2041327051605378,
            2244037852176483,
            2116336876147147,
            9616672544864,
        ),
        u64x4::new_const(
            969847387559191,
            1059119127679639,
            1764630094670633,
            364568045311834,
        ),
        u64x4::new_const(
            505938893153679,
            2075421412172902,
            326984153045666,
            1959549727324704,
        ),
        u64x4::new_const(
            1088715617911260,
            13917085151028,
            950568481355929,
            23687195265771,
        ),
        u64x4::new_const(
            1798284568673198,
            808382292203333,
            2214698741961545,
            610817203275867,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1731488929623777,
            1158815615106413,
            1491090861948525,
            1428384712900962,
        ),
        u64x4::new_const(
            722237139522457,
            1514290328911535,
            1366197913116230,
            1519472657321210,
        ),
        u64x4::new_const(
            246028966932273,
            1888239319448405,
            423720022211163,
            455243905681470,
        ),
        u64x4::new_const(
            738323403716001,
            1758018973481179,
            1180718299482318,
            1008495946606708,
        ),
        u64x4::new_const(
            334959381596119,
            1704599537529481,
            2172191232106896,
            13502508918495,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            273393076768079,
            427388720298603,
            1071733376018227,
            1715429388968611,
        ),
        u64x4::new_const(
            751776629892313,
            1965239102856011,
            541955408230119,
            831043488876080,
        ),
        u64x4::new_const(
            643718536393104,
            390543998404644,
            2176730661486279,
            499459234889079,
        ),
        u64x4::new_const(
            1482404333915009,
            865527293526285,
            507957951411713,
            216456252558825,
        ),
        u64x4::new_const(
            2210281256300231,
            1519357818277551,
            1257866936775246,
            1689605217672864,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            2135395168187905,
            2214400157568614,
            2032983817870823,
            1124945109072647,
        ),
        u64x4::new_const(
            1602820011758145,
            906675633903289,
            782700735390986,
            2067218823525601,
        ),
        u64x4::new_const(
            786785748926382,
            1433583123655616,
            905839404290873,
            2249680349963778,
        ),
        u64x4::new_const(
            1940824582370584,
            1610961256326291,
            285307858781375,
            1755588655461194,
        ),
        u64x4::new_const(
            233682812055333,
            2146114223476434,
            41132209533476,
            535292431776371,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            600257696476418,
            18449221564824,
            1422209458591138,
            239571584769716,
        ),
        u64x4::new_const(
            2056372917056980,
            1155290566623531,
            1252473955568148,
            1276690716882081,
        ),
        u64x4::new_const(
            246974369025311,
            658117221519903,
            2000380937898441,
            1351183273924850,
        ),
        u64x4::new_const(
            1803747363753112,
            1736801515030186,
            2025633577199091,
            603378480769167,
        ),
        u64x4::new_const(
            57348749438551,
            1893551220299655,
            657926732731806,
            1522499384853705,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            591809128842736,
            284860517232591,
            27436696863545,
            886306697195798,
        ),
        u64x4::new_const(
            2113192175751749,
            1405882509906423,
            561316282804847,
            835573846576266,
        ),
        u64x4::new_const(
            94407289485409,
            1781534171669004,
            2098782516531528,
            598529921520053,
        ),
        u64x4::new_const(
            1860137004504786,
            2197323407480349,
            1516772733981532,
            961740253777086,
        ),
        u64x4::new_const(
            1484139612868217,
            1593557644636881,
            838834937143441,
            36382198263380,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1165898865828562,
            1153420815042389,
            1068625028915785,
            1945927229911090,
        ),
        u64x4::new_const(
            843454394017146,
            571029655293754,
            386282254545998,
            1804608237584150,
        ),
        u64x4::new_const(
            370552451091100,
            1279105656351124,
            1864742949668631,
            2093071521726981,
        ),
        u64x4::new_const(
            1872542389052198,
            1679083953574330,
            349872262454465,
            1470311090717925,
        ),
        u64x4::new_const(
            685345654160323,
            319718985807814,
            1359932285384164,
            1410900103316331,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            2083666668832889,
            314624387816655,
            1496694646480345,
            1946728950459189,
        ),
        u64x4::new_const(
            1579153761571203,
            508771185291380,
            1002249659402007,
            551517831173801,
        ),
        u64x4::new_const(
            2132371471626150,
            1988122278556533,
            1552195130653890,
            1327637750292755,
        ),
        u64x4::new_const(
            118937099181527,
            382610380973142,
            634951529106471,
            382740054041699,
        ),
        u64x4::new_const(
            801287519643470,
            87822941589258,
            1908825350108451,
            1404208826499115,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            330347226380261,
            672119116965146,
            1761510370768005,
            1959200302484704,
        ),
        u64x4::new_const(
            1631876583009250,
            1684917718484264,
            1027256947805920,
            2174612545251129,
        ),
        u64x4::new_const(
            636668855699872,
            625187713984839,
            265886954766790,
            167898557908504,
        ),
        u64x4::new_const(
            1210974548180860,
            2051308710365526,
            907620584086428,
            1081788677970850,
        ),
        u64x4::new_const(
            621792955460854,
            1450945504745382,
            1666728650687828,
            977937146451674,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            24725936182267,
            2226765032752574,
            2036560083102883,
            2002351185719584,
        ),
        u64x4::new_const(
            1620080779405308,
            1493220053370419,
            2245691691038916,
            1152182628629603,
        ),
        u64x4::new_const(
            317928527147500,
            1855194218440212,
            979380281964169,
            861442286685289,
        ),
        u64x4::new_const(
            393308472784625,
            486143087279967,
            1234071346236405,
            777748237119399,
        ),
        u64x4::new_const(
            43850412814718,
            1497656407486446,
            744128331046695,
            1618035787321792,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1670169946550211,
            1230951698726438,
            806586940221293,
            23159779184607,
        ),
        u64x4::new_const(
            634011340979302,
            764182085034744,
            731065727766955,
            1737985776442180,
        ),
        u64x4::new_const(
            240492712141842,
            73976435954441,
            162810587166835,
            697230894340912,
        ),
        u64x4::new_const(
            1299745598348388,
            1359436039694544,
            1856609816731554,
            25228008461513,
        ),
        u64x4::new_const(
            2180690501932381,
            2161211192848458,
            87069466793408,
            2003456332883860,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1106932458043379,
            1675181364231371,
            1681785724775243,
            131824742557210,
        ),
        u64x4::new_const(
            1671649414647169,
            1827849994880670,
            1097958057111899,
            701956891169434,
        ),
        u64x4::new_const(
            2095539283710881,
            591029812888096,
            1699571518315654,
            1297589045812566,
        ),
        u64x4::new_const(
            1345612272298537,
            2166754730876055,
            2047982622154948,
            1785222806258129,
        ),
        u64x4::new_const(
            2181915268829890,
            1895697064378670,
            1288412327355885,
            1561075738281368,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            741330264098392,
            357073519729966,
            1603572339180975,
            433572083688575,
        ),
        u64x4::new_const(
            699685108971208,
            1719650727634959,
            1941668009419214,
            870374958347891,
        ),
        u64x4::new_const(
            385971389331537,
            11655507719711,
            94814615497633,
            515572102810609,
        ),
        u64x4::new_const(
            1396688200590426,
            1518748475144123,
            162386454324368,
            2083303971579002,
        ),
        u64x4::new_const(
            1511688632419263,
            251584258592336,
            545345887993880,
            1229840230314160,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1298668855706029,
            2017860934939344,
            2224150456036391,
            1925926576297971,
        ),
        u64x4::new_const(
            259522963883544,
            1312469129541229,
            1647530465049600,
            1113737129047154,
        ),
        u64x4::new_const(
            733193298663145,
            2115712816303403,
            897628702762311,
            116440277571901,
        ),
        u64x4::new_const(
            1998719395229750,
            1662774553684237,
            194395608126452,
            98796702872301,
        ),
        u64x4::new_const(
            2226158244229144,
            91961728239158,
            526869903032152,
            849263805316773,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            472779569333556,
            854477760843410,
            2070906720349401,
            734613359834689,
        ),
        u64x4::new_const(
            1771897100487404,
            1604024196006064,
            319699348925383,
            437152129592623,
        ),
        u64x4::new_const(
            627618365135361,
            1768642666037955,
            588564169143939,
            35295037750744,
        ),
        u64x4::new_const(
            220241884231278,
            319104161410840,
            1048165719448798,
            1583931089774347,
        ),
        u64x4::new_const(
            166479451884333,
            1623611819962804,
            59990366193679,
            900727256046987,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            1944687327687331,
            1328410791053991,
            2083980670913902,
            609396833380574,
        ),
        u64x4::new_const(
            1907563845734496,
            1385619047697883,
            869817384774457,
            106642388505109,
        ),
        u64x4::new_const(
            1006516581737154,
            1561918369633937,
            1921172883211450,
            2216650451558824,
        ),
        u64x4::new_const(
            1780506017391778,
            233064930371847,
            1332962603425752,
            1380075261612354,
        ),
        u64x4::new_const(
            1907624789747741,
            1310065402098523,
            1838275780706825,
            884225500782782,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            198729830692545,
            100156148743413,
            2140568641558859,
            2220606475942394,
        ),
        u64x4::new_const(
            1108788217903741,
            1706330932366163,
            2050449866410661,
            684907598542847,
        ),
        u64x4::new_const(
            1101958322366646,
            659427843062405,
            253899933868173,
            896574852821269,
        ),
        u64x4::new_const(
            1157052140740658,
            440541103447032,
            2173354981480949,
            604768603561932,
        ),
        u64x4::new_const(
            961238337866054,
            830849154351308,
            1643852412409441,
            1436749321770368,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            784870637473285,
            1180234052037572,
            2086951602998715,
            419328169540373,
        ),
        u64x4::new_const(
            1966862397394559,
            788036164772123,
            2024355635709481,
            1471696676696146,
        ),
        u64x4::new_const(
            1468884300957205,
            1408016588131185,
            2229595828577885,
            240413942963547,
        ),
        u64x4::new_const(
            1481791691942441,
            970648959691160,
            1635500996148197,
            2236917233261585,
        ),
        u64x4::new_const(
            31660820731028,
            801794768903647,
            1069092619607344,
            282652554845923,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            911659428682786,
            762502588057038,
            1311399152500807,
            1966922911783311,
        ),
        u64x4::new_const(
            1229849228728540,
            258161307933217,
            2140796867375541,
            1569345075547911,
        ),
        u64x4::new_const(
            1487354676143742,
            1818317546165791,
            811033554173350,
            1768788663337616,
        ),
        u64x4::new_const(
            450017165913234,
            962535873747168,
            2099104262993585,
            503030952485785,
        ),
        u64x4::new_const(
            1259958681304518,
            479589250923541,
            1503904042161640,
            706283657294305,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            794562643024291,
            198670993088241,
            1678984629358943,
            273399517554618,
        ),
        u64x4::new_const(
            188458991574433,
            1389872130156447,
            1461868931574746,
            795140878721432,
        ),
        u64x4::new_const(
            624046647169653,
            630363741191019,
            911018499983500,
            1410140563046579,
        ),
        u64x4::new_const(
            1675056174405076,
            632544713589250,
            795454163559811,
            1535271563341780,
        ),
        u64x4::new_const(
            25504547444781,
            812510098987855,
            51290042016232,
            1992260991700127,
        ),
    ])),
    CachedPoint(F51x4Reduced([
        u64x4::new_const(
            269968325452358,
            470932785179706,
            1684444304834150,
            1027482126748243,
        ),
        u64x4::new_const(
            457941065342419,
            2117377568137882,
            1209423706730905,
            2192403099717071,
        ),
        u64x4::new_const(
            1899046404863678,
            1359500336071762,
            1492389156724726,
            1455627081827750,
        ),
        u64x4::new_const(
            2016101061876546,
            1967000012916571,
            582539481696050,
            1197538178790094,
        ),
        u64x4::new_const(
            639684852217504,
            1799941252757449,
            1470016556327743,
            846111828965901,
        ),
    ])),
]);
